Spring的事物管理框架源码分析

前言

  • 现在Spring框架在Web项目中应用的越来越广泛,Spring框架与其它框架的融合设计的也特别的到位,譬如说Spring与Hibernate结合以后共同处理事务的框架,可是说设计思想非常巧妙,值得让人学习,前几篇博客小编发表了一篇Spring的声明式事务处理,今天由小编带领着大家一块来研究一下Spring的事务管理框架吧!

事务管理机制分析

  • 1、由程序告诉spring容器,什么样的目标方法采用什么样的事务策略,譬如说,在Service层中,一个Query开头的查询方法,它采用什么样的事务隔离机制,是采取只读事务还是读写事务等等。
  • 2、事务的处理:由spring容器来完成的,实际上,Spring容器只是配置好了,但是来完成具体事务操作的还是具体的TransactionManager,下面会介绍。
  • 3、程序员:此时程序员只需要关心CRDU操作,不比关心事务了,因为等一切配置做好以后,程序要只要按照规则做就行了,其实,具体的规则就是事务声明中的method配置。这个配置小编在Spring的声明式事务处理机制已经详细列出。小编给出一小段代码。
<tx:advice transaction-manager="transactionManager" id="tx">
        <tx:attributes>
        <!-- 
            name:目标方法的范围
            isolation:事物的隔离机制
            propagation:传播属性,解决事物的嵌套问题
            read-only:true(只读事物) false(读写事物)
         -->
            <tx:method name="save*" isolation="DEFAULT" propagation="REQUIRED"
                read-only="false" />
        </tx:attributes>
    </tx:advice>

简单框架类图

这里写图片描述

类图分析

从类图中我们可以看出,Spring框架平台给出一个PlatformTransactionManager借口,此接口有三个方法,一个是getTransaction(),一个是commit(), 最后一个是rollback(),然后让一个AbstractPlatformTransactionManager抽象类来实现此接口,最后分别让DataSourceTransactionManager、HibernateTransactionManager 和JdoTransactionManager来继承上面那个抽象类。

源码分析

PlatformTransactionManager(事物管理平台接口)


package org.springframework.transaction;

public interface PlatformTransactionManager {


    TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;

    void commit(TransactionStatus status) throws TransactionException;

    void rollback(TransactionStatus status) throws TransactionException;

}

此接口提供三个方法,由AbstractPlatformTransactionManager来实现,由于此抽象类方法甚多,我只贴出几个关键方法吧!

AbstractPlatformTransactionManager



public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, Serializable {
    ......
    ......

    private void processCommit(DefaultTransactionStatus status) throws TransactionException {
        try {
            boolean beforeCompletionInvoked = false;
            try {
                prepareForCommit(status);
                triggerBeforeCommit(status);
                triggerBeforeCompletion(status);
                beforeCompletionInvoked = true;
                boolean globalRollbackOnly = false;
                if (status.isNewTransaction() || isFailEarlyOnGlobalRollbackOnly()) {
                    globalRollbackOnly = status.isGlobalRollbackOnly();
                }
                if (status.hasSavepoint()) {
                    if (status.isDebug()) {
                        logger.debug("Releasing transaction savepoint");
                    }
                    status.releaseHeldSavepoint();
                }
                else if (status.isNewTransaction()) {
                    if (status.isDebug()) {
                        logger.debug("Initiating transaction commit");
                    }

                    doCommit(status);//此方法是抽象方法,谁继承,谁实现,本片文章中介绍HibernateTransactionManager类来实现此方法

                }
                ......
                ......

            }

            ......
            ......
    }



    public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {

        Object transaction = doGetTransaction(); //此方法是抽象方法,谁继承,谁实现,本片文章中介绍HibernateTransactionManager类来实现此方法

        ......
        ......
        ......
    }
}

HibernateTransactionManager

public class HibernateTransactionManager extends AbstractPlatformTransactionManager
        implements ResourceTransactionManager, BeanFactoryAware, InitializingBean {

    ......
    ......
    ......


    protected Object doGetTransaction() {

        SessionHolder sessionHolder =
                (SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory());//
        if (sessionHolder != null) {
            if (logger.isDebugEnabled()) {
                logger.debug("Found thread-bound Session [" +
                        SessionFactoryUtils.toString(sessionHolder.getSession()) + "] for Hibernate transaction");
            }
            txObject.setSessionHolder(sessionHolder);
        }
        else if (this.hibernateManagedSession) {
            try {
                Session session = getSessionFactory().getCurrentSession();得到Session,为开启事务做准备。。。。
                if (logger.isDebugEnabled()) {
                    logger.debug("Found Hibernate-managed Session [" +
                            SessionFactoryUtils.toString(session) + "] for Spring-managed transaction");
                }
                txObject.setExistingSession(session);
            }
            catch (HibernateException ex) {
                throw new DataAccessResourceFailureException(
                        "Could not obtain Hibernate-managed Session for Spring-managed transaction", ex);
            }
        }

        ......
        ......

        return txObject;
    }


    protected void doCommit(DefaultTransactionStatus status) {
        HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction();
        if (status.isDebug()) {
            logger.debug("Committing Hibernate transaction on Session [" +
                    SessionFactoryUtils.toString(txObject.getSessionHolder().getSession()) + "]");
        }
        try {
            txObject.getSessionHolder().getTransaction().commit();//事务再此提交
        }
        catch (org.hibernate.TransactionException ex) {
            ......
        }
        catch (HibernateException ex) {
            ......
        }
    }

    ......
    ......
    ......
}

小结

  • spring在调用具体的事务管理器之前做了一些准备工作,譬如提前设置事务的读写策略,而这些事务策略是公共的东西,是写在spring的配置文件中的,所以这些公共内容的处理由抽象类中去做,然后在抽象类中留一些让具体事务管理器实现的抽象方法,像doCommit()、doRollback()等。Spring的这种设计思想确实巧妙,值得我们学习。
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 21
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值